package com.docker.fy.service.impl;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import com.docker.common.core.domain.AjaxResult;
import com.docker.common.core.domain.entity.SysUser;
import com.docker.common.core.domain.model.LoginUser;
import com.docker.common.utils.DateUtils;
import com.docker.common.utils.SecurityUtils;
import com.docker.fy.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.docker.fy.domain.DoctorRegistration;
import com.docker.fy.service.IDoctorRegistrationService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 工作台接诊Service业务层处理
 *
 * @author ruoyi
 * @date 2025-04-09
 */
@Service
public class DoctorRegistrationServiceImpl implements IDoctorRegistrationService {
    @Autowired
    private DoctorRegistrationMapper doctorRegistrationMapper;
    @Autowired
    private FyPrescriptionMapper prescriptionMapper;
    @Autowired
    private FyPrescriptionMedicineMapper prescriptionMedicineMapper;
    @Autowired
    private FyDockerDrugMapper dockerDrugMapper;
    @Autowired
    private FyPrescriptionProjectMapper prescriptionProject;
    @Autowired
    private DoctorPrescriptionAdditionalMapper doctorPrescriptionAdditionalMapper;
    @Autowired
    private FyInspectMapper inspectMapper;
    @Autowired
    private FyOrderMapper orderMapper;
    @Autowired
    private FyDoctorPatientMapper doctorPatientMapper;
    @Autowired
    private FyPatientMapper patientMapper;
    @Autowired
    private FyVipMapper vipMapper;

    /**
     * 查询工作台接诊
     *
     * @param id 工作台接诊主键
     * @return 工作台接诊
     */
    @Override
    public DoctorRegistration selectDoctorRegistrationById(Long id) {
        return doctorRegistrationMapper.selectDoctorRegistrationById(id);
    }

    /**
     * 查询工作台接诊列表
     *
     * @param doctorRegistration 工作台接诊
     * @return 工作台接诊
     */
    @Override
    public List<DoctorRegistration> selectDoctorRegistrationList(DoctorRegistration doctorRegistration) {
        return doctorRegistrationMapper.selectDoctorRegistrationList(doctorRegistration);
    }

    /**
     * 新增工作台接诊
     *
     * @param doctorRegistration 工作台接诊
     * @return 结果
     */
    @Override
    public int insertDoctorRegistration(DoctorRegistration doctorRegistration) {
        doctorRegistration.setCreateTime(DateUtils.getNowDate());
        return doctorRegistrationMapper.insertDoctorRegistration(doctorRegistration);
    }

    /**
     * 修改工作台接诊
     *
     * @param doctorRegistration 工作台接诊
     * @return 结果
     */
    @Override
    public int updateDoctorRegistration(DoctorRegistration doctorRegistration) {
        return doctorRegistrationMapper.updateDoctorRegistration(doctorRegistration);
    }

    /**
     * 批量删除工作台接诊
     *
     * @param ids 需要删除的工作台接诊主键
     * @return 结果
     */
    @Override
    public int deleteDoctorRegistrationByIds(Long[] ids) {
        return doctorRegistrationMapper.deleteDoctorRegistrationByIds(ids);
    }

    /**
     * 删除工作台接诊信息
     *
     * @param id 工作台接诊主键
     * @return 结果
     */
    @Override
    public int deleteDoctorRegistrationById(Long id) {
        return doctorRegistrationMapper.deleteDoctorRegistrationById(id);
    }

    @Override
    @Transactional
    public AjaxResult savePrescription(Map map) {
//        AjaxResult ajaxResult = new AjaxResult();
        //1先保存处方信息
        int prescriptionId = addPrescription(map);
        //获取处方id
        //2再保存处方药品信息  传递处方id和map
        addPrescriptionMedicine(map,prescriptionId);
        //3修改挂号表的状态
        updateRegistrationStatus(map);
        //4药品表减库存
        updateMedicineStock(map);
        //5保存处方检查项目信息
        addPrescriptionCheck(map,prescriptionId);
        //6保存处方附加费用信息
        addPrescriptionExtra(map,prescriptionId);
        //7保存病历信息
        addMedicalRecord(map,prescriptionId);
        //8保存订单信息
        addOrder(map, prescriptionId);
        //9保存积分信息
        addIntegral(map);
        return AjaxResult.success();
        //TODO 10保存出库信息
//        addOutbound(map,prescriptionId);
    }

    @Override
    public List<Map> getAllPatientList() {
        //查询所有患者信息
        List<Map> patientList = patientMapper.selectAllPatientList();
//        System.out.println(patientList);
        return patientList;
    }

    //保存出库信息
//    private AjaxResult addOutbound(Map map, int prescriptionId) {
//        //出库信息map
//        Map outboundMap = new HashMap();
//        //出库单号   CB+年月日时分秒
//        // 定义日期时间格式
//        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
//        // 获取当前时间并格式化
//        String timestamp = LocalDateTime.now().format(formatter);
//        String drugs_out_id = "CB" + timestamp;
//        map.put("drugs_out_id",drugs_out_id);
//        //医生信息
//        Map myUser = (Map) map.get("MyUser");
//        //保存医生姓名
//        outboundMap.put("doctor_name",myUser.get("userName"));
//        //出库类型
//        outboundMap.put("drugs_out_type","科室领药");
//        //制单人员
//        //当前登录人
//        LoginUser loginUser = SecurityUtils.getLoginUser();
//        //当前登陆人姓名
//        String userName = loginUser.getUsername();
//        outboundMap.put("drugs_out_creation_staff",userName);
//        //
//        return AjaxResult.success();
//    }
    //保存积分信息，同时积分到达一定额度升为会员
    private AjaxResult addIntegral(Map map) {
        //积分map
        Map integralMap = new HashMap();
        //患者信息
        Map myPatient = (Map) map.get("MyPatient");
        //患者id
        integralMap.put("patient_id",myPatient.get("id"));
        //最终消费（加多少积分）
        integralMap.put("points",map.get("MyEndTotalAmount"));
        //先跟据患者id查询积分
        //患者id
        int id = (int) myPatient.get("id");
//        Map integral = doctorPatientMapper.selectIntegral(id);
        Map integral = vipMapper.selectIntegral(id);
        //没有数据就插入，有数据就更新
//        System.out.println(Double.parseDouble(integral.get("balance").toString()) < Double.parseDouble(map.get("MyEndTotalAmount").toString()));
        if (integral == null || Double.parseDouble(integral.get("balance").toString()) < Double.parseDouble(map.get("MyEndTotalAmount").toString())){
            //新增
            //保存积分
//            doctorPatientMapper.addIntegral(integralMap);
//            vipMapper.addIntegral(integralMap);
//            return AjaxResult.error("余额不足请去充值");
            throw new RuntimeException("余额不足请去充值");
        }else{
            //余额减少
            double balance = Double.parseDouble(integral.get("balance").toString()) - Double.parseDouble(integralMap.get("points").toString());
//            System.out.println(Double.parseDouble(integral.get("balance").toString()));
//            System.out.println(Double.parseDouble(integralMap.get("points").toString()));
//            System.out.println("balance:" + balance);
            integralMap.put("balance",balance);
            //更新积分double类型
//            System.out.println(integral.get("points").toString());
//            System.out.println(integralMap.get("points").toString());
            double points = Double.parseDouble(integral.get("points").toString()) + Double.parseDouble(integralMap.get("points").toString());
            integralMap.put("points",points);
            //增加累计消费
            double consumption = Double.parseDouble(integral.get("consumption").toString()) + Double.parseDouble(integralMap.get("points").toString());
            integralMap.put("consumption",consumption);

            //如果积分大于1000，就升为会员
            if (points >= 1000){
                integralMap.put("vip_grade",1);
            }else{
                integralMap.put("vip_grade",0);
            }
            //
            //更新积分
//            doctorPatientMapper.updateIntegral(integralMap);
            vipMapper.updateIntegral(integralMap);
            //跟新患者表数据
            Map patientMap = new HashMap();
            patientMap.put("id",id);
            patientMap.put("vipType",integralMap.get("vip_grade"));
            patientMapper.updatePatient(patientMap);
        }
        return AjaxResult.success();
    }
    //保存订单信息
    private AjaxResult addOrder(Map map, int prescriptionId) {
//        System.out.println(map);
        // 订单信息map
        Map orderMap = new HashMap();
        //订单类型 0 处方 1零售
        orderMap.put("ordertype", 0);
        //医生信息
        Map myUser = (Map) map.get("MyUser");
//        System.out.println(myUser);
        //医生id
        orderMap.put("doctor_id",myUser.get("userId"));
        //患者id
        Map myPatient = (Map) map.get("MyPatient");
        orderMap.put("patient_id",myPatient.get("id"));
        //总费用
        orderMap.put("totalcost",map.get("MyEndTotalAmount"));
        //处方id
        orderMap.put("prescription_id",prescriptionId);

        //当前登录用户
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
//        System.out.println(user);
        //当前登录用户姓名
        orderMap.put("tollcollector",user.getUserName());
//        orderMap.put("tollcollector",user.getUserId());
        //保存订单
        orderMapper.add(orderMap);
        return AjaxResult.success();
    }
    //保存病历信息
    private AjaxResult addMedicalRecord(Map map, int prescriptionId) {
        // 病历信息
        Map medicalRecordInfo = (Map) map.get("MyMedicalForm");
//        System.out.println(medicalRecordInfo);

        // 病历信息map
        Map medicalRecordMap = new HashMap();

        // 将病历信息放入map中
        // 患者id
        medicalRecordMap.put("patient_id", medicalRecordInfo.get("patientCard"));
        // 体温
        medicalRecordMap.put("body_temperature", medicalRecordInfo.get("temperature"));
        // 呼吸
        medicalRecordMap.put("respiration", medicalRecordInfo.get("breathing"));
        // 脉搏
        medicalRecordMap.put("pluses", medicalRecordInfo.get("pulse"));
        // 血压
        medicalRecordMap.put("blood_pressure", medicalRecordInfo.get("bloodPressure"));
        // 身高
        medicalRecordMap.put("height", medicalRecordInfo.get("height"));
        // 体重
        medicalRecordMap.put("weight", medicalRecordInfo.get("weight"));
        // 血糖
        medicalRecordMap.put("blood_glucose", medicalRecordInfo.get("bloodSugar"));
        // 血脂
        medicalRecordMap.put("blood_lipid", medicalRecordInfo.get("bloodFat"));

        // 发病日期 - 将日期格式转换为yyyy-MM-dd
        if (medicalRecordInfo.get("onsetDate") != null) {
            String isoDate = medicalRecordInfo.get("onsetDate").toString();
            LocalDateTime dateTime = LocalDateTime.parse(isoDate, DateTimeFormatter.ISO_DATE_TIME);
            String formattedDate = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            medicalRecordInfo.put("onsetDate", formattedDate);
            medicalRecordMap.put("onset_date", formattedDate);
        }

        // 将列表类型字段转换为逗号分隔的字符串
        // 主诉
        medicalRecordMap.put("complaints_info", convertListToString(medicalRecordInfo.get("mainComplaint")));
        // 现病史
        medicalRecordMap.put("present_illness", convertListToString(medicalRecordInfo.get("presentIllness")));
        // 既往史
        medicalRecordMap.put("medical_history", convertListToString(medicalRecordInfo.get("pastHistory")));
        // 过敏史
        medicalRecordMap.put("allergic_history", convertListToString(medicalRecordInfo.get("allergyHistory")));
        // 个人史
        medicalRecordMap.put("personal_history", convertListToString(medicalRecordInfo.get("personalHistory")));
        // 家族史
        medicalRecordMap.put("family_history", convertListToString(medicalRecordInfo.get("familyHistory")));
        // 辅助检查
        medicalRecordMap.put("auxiliary_examination", convertListToString(medicalRecordInfo.get("auxiliaryExam")));
        // 治疗意见
        medicalRecordMap.put("treatment_advice", convertListToString(medicalRecordInfo.get("treatmentAdvice")));
        // 备注
        medicalRecordMap.put("remark", medicalRecordInfo.get("remarks"));

        // 保存病历
        inspectMapper.add(medicalRecordMap);
        return AjaxResult.success();
    }

    // 辅助方法：将List转换为逗号分隔的字符串
    private String convertListToString(Object listObj) {
        if (listObj == null) {
            return null;
        }

        if (listObj instanceof List) {
            List<?> list = (List<?>) listObj;
            return list.stream()
                    .map(Object::toString)
                    .collect(Collectors.joining(", "));
        }

        return listObj.toString();
    }
    //保存处方附加费用信息
    private AjaxResult addPrescriptionExtra(Map map, int prescriptionId) {
        //附加费用
        List<Map> extraList = (List<Map>) map.get("MySelectedAdditionalFeesId");
        //遍历extraList
        for (Map extra : extraList) {
//            System.out.println(extra);
            //附加费用id
            int extraId = (int) extra.get("feeId");
            //调用方法去添加处方附加费用
            doctorPrescriptionAdditionalMapper.addPrescriptionExtra(prescriptionId, extraId);
        }
        return AjaxResult.success();
    }
    //保存处方检查项目信息
    private AjaxResult addPrescriptionCheck(Map map, int prescriptionId) {
        //检查项目
        List<Map> checkList = (List<Map>) map.get("MySelectedExaminationsId");
        //处方id
//        System.out.println(prescriptionId);
        //遍历checkList
        for (Map check : checkList) {
//            System.out.println(check);
            //检查项目id
            int checkId = (int) check.get("projectId");
            //调用方法去添加处方检查项目
            prescriptionProject.addPrescriptionCheck(prescriptionId, checkId);
        }
        return AjaxResult.success();
    }
    //药品表减库存
    private AjaxResult updateMedicineStock(Map map) {
        //获取药品id和数量
        List<Map> medicineList = (List<Map>) map.get("MySelectedMedicinesIdAndQuantity");
        //遍历medicineList
        for (Map medicine : medicineList) {
//            System.out.println(medicine);
            //获取药品id
            int medicineId = (int) medicine.get("drugId");
            //获取数量
            int quantity = (int) medicine.get("quantity");
            //现根据药品id查询药品表中库存
            int stock = dockerDrugMapper.selectMedicineStockById(medicineId);
            //如果库存大于出库数量
            if (stock >= quantity) {
                //库存减去出库数量
                stock -= quantity;
                //调用方法去更新药品表
                dockerDrugMapper.updateMedicineStockById(medicineId, stock);
            }else{
                //库存小于出库数量
//                return AjaxResult.error("库存不足");
                throw new RuntimeException("库存不足");
            }
        }
        return AjaxResult.success();
    }

    //修改挂号表的状态
    private AjaxResult updateRegistrationStatus(Map map) {
        //获取挂号单号
        int myPrescriptionFormId = (int) map.get("MyPrescriptionFormId");
//        System.out.println(myPrescriptionFormId);
        doctorRegistrationMapper.updateRegistrationStatus(myPrescriptionFormId);
        return AjaxResult.success();
    }
    //保存处方药品信息
    public AjaxResult addPrescriptionMedicine(Map map,int prescriptionId) {
        //处方药品id和数量
        List<Map> medicineList = (List<Map>) map.get("MySelectedMedicinesIdAndQuantity");
        //处方药品List<Map>
        List<Map> prescriptionMedicineList = new ArrayList<>();
        //遍历medicineList
        for (Map medicine : medicineList) {
            Map prescriptionMedicineMap = new HashMap();
            //将处方id和药品id和数量放入map中
            prescriptionMedicineMap.put("prescription_id", prescriptionId);
            prescriptionMedicineMap.put("medicine_id", medicine.get("drugId"));
            prescriptionMedicineMap.put("number", medicine.get("quantity"));
            //将map放入list中
            prescriptionMedicineList.add(prescriptionMedicineMap);
        }

        //调用方法去添加处方药品
        prescriptionMedicineMapper.add(prescriptionMedicineList);
        return AjaxResult.success();
    }
    //保存处方信息并返回处方id
    public int addPrescription(Map map) {
        //处方信息
        Map prescriptionInfo = (Map) map.get("MyPrescriptionForm");
//        System.out.println(prescriptionInfo);
        //患者信息
        Map patientInfo = (Map) map.get("MyPatient");
        //医生信息
        Map myUser = (Map) map.get("MyUser");
        //医生id
//        patientInfo.put("doctor_id",myUser.get("userId"));
//        System.out.println(patientInfo);
        //处方map
        Map prescriptionMap = new HashMap();
        //诊断
        //将诊断信息转换为字符串，每个值之间用逗号分隔
        Object diagnosisObj = prescriptionInfo.get("diagnosis");
        String diagnosis = "";
        if (diagnosisObj instanceof Collection) {
            diagnosis = ((Collection<?>) diagnosisObj).stream()
                    .filter(Objects::nonNull)
                    .map(Object::toString)
                    .collect(Collectors.joining(","));
        } else if (diagnosisObj != null) {
            diagnosis = diagnosisObj.toString();
        }

        prescriptionMap.put("diagnosis", diagnosis);
        //医嘱
        //将医嘱信息转换为字符串，每个值之间用逗号分隔
        Object adviceObj = prescriptionInfo.get("advice");
        String advice = "";
        if (adviceObj instanceof Collection) {
            advice = ((Collection<?>) adviceObj).stream()
                    .filter(Objects::nonNull)
                    .map(Object::toString)
                    .collect(Collectors.joining(","));
        } else if (adviceObj != null) {
            advice = adviceObj.toString();
        }

        prescriptionMap.put("advice", advice);
        //患者id
        prescriptionMap.put("patient_id", patientInfo.get("id"));
        //处方类型  0为非模板
        prescriptionMap.put("type", 0);
//        System.out.println(prescriptionMap);
        //调用方法去添加处方
        prescriptionMapper.add(prescriptionMap);
        //返回处方id
        int prescriptionId = ((Number)prescriptionMap.get("id")).intValue();
        return prescriptionId;
    }
}
